const _ = require('lodash')
const fp = require('lodash/fp')

// 数据
// horsepower 马力， dollar_value 价格，in_stack 库存
const cars = [
    { name: "Ferrari FF", horsepower: 660, dollar_value: 700000, in_stack: true},
    { name: "Spyker C12 Zagato", horsepower: 650, dollar_value: 648000, in_stack: false},
    { name: "Jaguar XKR-S", horsepower: 550, dollar_value: 132000, in_stack: false},
    { name: "Audi R8", horsepower: 525, dollar_value: 114200, in_stack: false},
    { name: "Astom Martin One-77", horsepower: 750, dollar_value: 1850000, in_stack: true},
    { name: "Pagani Huayra", horsepower: 700, dollar_value: 1300000, in_stack: false},
]

// 练习一
// 使用函数组合fp.flowRight() 重新实现下面这个函数
// let isLastInStack = function (cars) {
//     // 获取最后一条数据
//     let last_car = fp.last(cars)
//     // 获取最后一条数据的 in_stack 属性值
//     return fp.prop('in_stack', last_car)
// }

let isLastInStack = fp.flowRight(fp.prop('in_stack'), fp.last)
console.log(isLastInStack(cars))


// 练习二
// 使用fp.flowRight() fp.prop() 和fp.first() 获取第一个car的name
let firstName = fp.flowRight(fp.prop('name'), fp.first)
console.log(firstName(cars))


// 练习三
// 使用帮助函数 _average 重构 averageDollarValue 使用函数组合的方式实现
let _average = function (xs) {
    return fp.reduce(fp.add, 0, xs) / xs.length
}

// let averageDollarValue = function (cars) {
//     let dollar_values = fp.map(function (car) {
//         return car.dollar_value
//     }, cars)
//     return _average(dollar_values)
// }


let values = function (cars) {
    return fp.map(function (car) {
        return car.dollar_value
    }, cars) 
}
let averageDollarValue = fp.flowRight(_average, values)


console.log(averageDollarValue(cars))


// 练习四
// 使用flowRight 写一个sanitizeNames() 函数，返回一个下换线连接的小写字符串，把数组中的name转换为
// 这种形式：例如：sanitizeNames(['Hello World]) => ['hello_world']

let _underscore = fp.replace(/\W+/g, '_')

let sanitizeNames = fp.map((val) => {
    return fp.flowRight(fp.toLower, _underscore)(val)
}) 

console.log(sanitizeNames(['Hello World', 'I Love You']))



// 代码2
const { Maybe, Container} = require('./support.js') 
// let r = Container.map(3)
// console.log(r())

// 练习一
// 使用fp.add(x, y)和fp.map(f, x) 创建一个能让functor里的值增加的函数ex1
let maybe = Maybe.of([5, 6, 1])
let ex1 = maybe
            .map(fp.map((val) => {
                return fp.add(val, 2)
            }))

console.log(ex1)


// 练习二
// 实现一个函数ex2，能够使用fp.first 获取列表的第一个元素
let xs = Container.of(['do', 'ray', 'me', 'fa', 'so', 'la', 'xi', 'do'])

let ex2 = xs.map(fp.first)
console.log(ex2)


// 练习三
// 实现一个函数ex3，使用safeProp和fp.first找到user的名字的首字母
let safeProp = fp.curry(function (x, o) {
    return Maybe.of(o[x])
})
let user = { id: 2, name: 'Albert'}
let ex3 = Container.of(user)
            .map(safeProp('name'))
            .map(val => val._value)
            .map(fp.first)

console.log(ex3)


// 练习四
// 使用Maybe重写ex4，不要有if语句
// let ex4 = function (n) {
//     if (n) { return parseInt(n) }
// }

let ex4 = function (n) {
    let r = Maybe.of(n)
                .map(fp.isEmpty)
        console.log(r)
        
    // console.log(r)
    return r._value || r.map(parseInt)
}

console.log(ex4(1232))